package fr.ants.controller.listener;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import fr.ants.controller.clock.Clock;
import fr.ants.controller.command.MoveCommand;
import fr.ants.controller.command.NewNestCommand;
import fr.ants.controller.command.NewObstacleCommand;
import fr.ants.controller.command.NewResourceCommand;
import fr.ants.view.Selection;
import fr.ants.view.component.CanvasContextMenu;
import fr.ants.view.panel.Canvas;

/**
 * Listener on the canvas to open the pop-up menu.
 * 
 * @author Guillaume Ruscassie
 * 
 */
public class CanvasListener implements MouseListener, MouseMotionListener {

	/**
	 * control buttons listener.
	 */
	private ButtonsListener buttonsListener;

	/**
	 * Clock.
	 */
	private Clock clock;

	/**
	 * Canvas
	 */
	private Canvas canvas;
	/**
	 * command to create a new obstacle.
	 */
	private NewObstacleCommand newObstacleCommand;
	/**
	 * command to create a new resource.
	 */
	private NewResourceCommand newResourceCommand;
	/**
	 * command to create a new nest.
	 */
	private NewNestCommand nestCommand;

	/**
	 * Build.
	 * 
	 * @param buttonsListener
	 *            listener for the buttons
	 * @param clock
	 *            Clock
	 * @param canvas
	 *            canvas
	 * @param newObstacleCommand
	 *            command
	 * @param newResourceCommand
	 *            command
	 * @param nestCommand
	 *            command
	 */
	public CanvasListener(ButtonsListener buttonsListener, Clock clock,
			Canvas canvas, NewObstacleCommand newObstacleCommand,
			NewResourceCommand newResourceCommand, NewNestCommand nestCommand) {
		this.canvas = canvas;
		this.buttonsListener = buttonsListener;
		this.clock = clock;
		this.newObstacleCommand = newObstacleCommand;
		this.nestCommand = nestCommand;
		this.newResourceCommand = newResourceCommand;
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON3) {
			canvas.setSelection(Selection.CLICK_RIGHT);
			canvas.setSelectedXY(e.getX(), e.getY());
			CanvasContextMenu menu = new CanvasContextMenu(buttonsListener,
					clock, canvas);
			menu.show(e.getComponent(), e.getX(), e.getY());
		} else
		// if it's a click left then we keep the coordinates
		if (e.getButton() == MouseEvent.BUTTON1) {
			switch (canvas.getSelection()) {
			case OBSTACLE:
				canvas.setSelectedXY(e.getX(), e.getY());
				newObstacleCommand.execute();
				break;
			case NEST:
				canvas.setSelectedXY(e.getX(), e.getY());
				nestCommand.execute();
				break;
			case RESOURCE:
				canvas.setSelectedXY(e.getX(), e.getY());
				newResourceCommand.execute();
				break;
			default:
				break;
			}
		}
	}

	@Override
	public void mousePressed(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON1) {
			switch (canvas.getSelection()) {
			case SELECTION:
				if (canvas.getGrid() != null
						&& canvas.getGrid().getNodes().length > 0
						&& canvas.getGrid().getNodes()[0].length > 0)
					canvas.setSelectedXY(e.getX(), e.getY());
				break;
			default:
				break;
			}
		}

	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// if it's a click left we move the component
		if (e.getButton() == MouseEvent.BUTTON1) {
			if (canvas.getSelection().equals(Selection.SELECTION)
					&& canvas.getSelectedGridX() != null
					&& canvas.getSelectedGridY() != null) {
				MoveCommand m = new MoveCommand(canvas, clock, e.getX(),
						e.getY());
				m.execute();
			}
		}
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// do nothing
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// do nothing
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		switch (canvas.getSelection()) {
		case OBSTACLE:
			canvas.setSelectedXY(e.getX(), e.getY());
			newObstacleCommand.execute();
			break;
		case RESOURCE:
			canvas.setSelectedXY(e.getX(), e.getY());
			newResourceCommand.execute();
			break;
		default:
			break;
		}

	}

	@Override
	public void mouseMoved(MouseEvent e) {
		/*
		 * System.out.println("       X: " + e.getX() + " Y: " + e.getY());
		 * System.out.println("Canvas X: " + (int)
		 * canvas.getMousePosition().getX() + " Y: " + (int)
		 * canvas.getMousePosition().getY());
		 */

	}

}
